import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.Timer;


public class MainGUI {
   JFrame frame;
   JPanel background;
   MyMapPanel MapPanel;
   MyInfoPanel InfoPanel;
   Client theClient;
   Clock turnclock;
	
   Font bigFont = new Font("serif", Font.BOLD, 28);
   Font regularFont = new Font("Time New Roman", Font.PLAIN, 20);
   
   int turn = 0;
   
   public MainGUI(Client theClient){	   	   	   
			
			frame = new JFrame(theClient.GetPlayer().GetName() + "'s Game");
			BorderLayout backgroundlayout = new BorderLayout();
			background = new JPanel(backgroundlayout);
			background.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
			
			MapPanel = new MyMapPanel(); 
			InfoPanel = new MyInfoPanel(); 
			
			frame.getContentPane().add(BorderLayout.CENTER, MapPanel);
			frame.getContentPane().add(BorderLayout.EAST, InfoPanel);
	
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.setSize(800, 600);
			MapPanel.setPreferredSize(new Dimension(600, 600));
			frame.setVisible(true);
   }
	
   public void Update(){
	   MapPanel.UpdateMapPanel();  
	   InfoPanel.UpdateInfoPanel();
	   frame.repaint();       
   }
     
   class MyTerritoryPanel extends JPanel{
	   JLabel amount;
	   public MyTerritoryPanel(){
		   amount = new JLabel();
		   this.add(amount);
	   }
	   
	   public void setlabel(int s){
		   amount.setText(String.valueOf(s));
	   }
   }
   
   public class MyMapPanel extends JPanel{
	   ArrayList<MyTerritoryPanel> TerritoryGrid;
       public MyMapPanel(){	   
    	   GridLayout MapPanelLayout = new GridLayout(5, 5);	   
    	   MapPanelLayout.setVgap(1);	   
    	   MapPanelLayout.setHgap(2);
	       TerritoryGrid = new ArrayList<MyTerritoryPanel>();
	       this.setLayout(MapPanelLayout);
    	   for (int i = 0; i < 5; i++)
    		   for (int j = 0; j < 5; j++){
     			   MyTerritoryPanel t = new MyTerritoryPanel();
				   t.setBackground(theClient.GetMap().getTerritory(i, j).GetOwner().GetHue());  
                   t.setlabel(theClient.GetMap().getTerritory(i, j).GetAmount());
                   TerritoryGrid.add(t);
    			   this.add(t);
    		   } 
       }
       
       public void UpdateMapPanel(){
    	   for (int i = 0; i < 5; i++)
    		   for (int j = 0; j < 5; j++){
    		       MyTerritoryPanel t = TerritoryGrid.get(i * 5 + j);
    			   t.setBackground(theClient.GetMap().getTerritory(i, j).GetOwner().GetHue());  
                   t.setlabel(theClient.GetMap().getTerritory(i, j).GetAmount());
       }
       }
   }
   
   class MyInfoPanel extends JPanel{     
	   MyTurnPanel TurnPanel;
	   MyOrderPanel OrderPanel;
	   
	   public MyInfoPanel(){
    	   this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
    	   TurnPanel = new MyTurnPanel();
    	   OrderPanel = new MyOrderPanel();
    	   this.add(TurnPanel);
    	   this.add(OrderPanel);
       } 
	   
	   public void UpdateInfoPanel(){
		   TurnPanel.UpdateTurnPanel();
		   OrderPanel.UpdateOrderPanel();
	   }
   }

   class MyTurnPanel extends JPanel{
    	   JLabel turnnumber, totalterritories, numterritories, totaltroops, numtroops;
    	   Clock turnclock;
    	   
    	   public MyTurnPanel(){
    		   GridLayout TurnPanelLayout = new GridLayout(3, 2);
    		   TurnPanelLayout.setVgap(2);
    		   TurnPanelLayout.setHgap(2);
    		   
    		   turnnumber = new JLabel("Turn " + String.valueOf(turn));
    		   turnnumber.setFont(bigFont);
    		   turnclock = new Clock();
    	       totalterritories = new JLabel("Total Territories: ");
    	       totalterritories.setFont(regularFont);
    	       numterritories = new JLabel(String.valueOf(theClient.GetPlayer().GetTerritoryList().size()));
    	       totaltroops = new JLabel("Total Troops: ");
    	       totaltroops.setFont(regularFont);
    	       numtroops = new JLabel(String.valueOf(theClient.GetPlayer().GetAmount()));
               
               this.add(turnnumber);
               this.add(turnclock);
               this.add(totalterritories);
               this.add(numterritories);
               this.add(totaltroops);
               this.add(numtroops);
    	   }
    	   public void UpdateTurnPanel(){
    		   turnclock.Reset();
    		   turnnumber.setText("Turn " + String.valueOf(turn));
    		   numterritories.setText(String.valueOf(theClient.GetPlayer().GetTerritoryList().size()));
    		   numtroops.setText(String.valueOf(theClient.GetPlayer().GetAmount()));
    	   }
       }
   
   class Clock extends JPanel{
 	   JLabel currenttime;
 	   int minute, second;
 	   Timer CountdownTimer;
 	   
 	   public Clock(){
 		   minute = 5;
 		   second = 0;
 		   currenttime = new JLabel(String.valueOf(minute) + ":" + String.valueOf(second));
 	       currenttime.setFont(bigFont);
 	       this.add(currenttime);
 	       CountdownTimer = new Timer();
 	       CountdownTimer.schedule(new Countdown(), 0, 1000);
 	   }
 	   
 	   public void Reset(){
 		   CountdownTimer.cancel();
 		   minute = 5;
 		   second = 0;
 		   CountdownTimer.schedule(new Countdown(), 1000);
 	   }
 	   
 	   class Countdown extends TimerTask{
 		   public void run(){
 			   if (second == 0) {
 				   second = 59;
 				   minute --;
 			   }
 			   else second--;
 			   currenttime.setText(String.valueOf(minute) + ":" + String.valueOf(second));
 			   turnclock.repaint();  
 			   if (minute == 0)
 				   CountdownTimer.cancel();
 	   }
 	}
    }
   
   class MyOrderPanel extends JPanel{
       Box basebox, labelbox, enterbox;
       JTextField num, sx, sy, dx, dy;
       JButton submitorderbutton;
       JList<String> ordertypelist;
       boolean beginattack;
       
	   public MyOrderPanel(){

    	   GridLayout TurnPanelLayout = new GridLayout(7, 2);
 		   TurnPanelLayout.setVgap(1);
 		   TurnPanelLayout.setHgap(5);
 		   this.setLayout(TurnPanelLayout);
 		   
    		JLabel typelabel = new JLabel("Order Type");	
    		JLabel numberlabel = new JLabel("Number");	
    		JLabel sourceXlabel = new JLabel("SourceX");	
    		JLabel sourceYlabel = new JLabel("SourceY");	
    		JLabel destinationXlabel = new JLabel("DestinationX");	
    		JLabel destinationYlabel = new JLabel("DestinationY");  
    		
    		String [] listEntries = {"Move", "Attack"};		
    		ordertypelist = new JList<String>(listEntries);	
    		JScrollPane scroller = new JScrollPane(ordertypelist);
    		scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    		scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    		ordertypelist.setVisibleRowCount(1);
    		beginattack = false;
    		
    		ordertypelist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);	
    		num = new JTextField(5);
    		sx = new JTextField(3);	
    		sy = new JTextField(3);	
    		dx = new JTextField(3);	
    		dy = new JTextField(3);	
    		
    		this.add(typelabel);
    		this.add(ordertypelist);
     		this.add(numberlabel);
    		this.add(num);
    		this.add(sourceXlabel);
    		this.add(sx);
    		this.add(sourceYlabel);
    		this.add(sy);	
    		this.add(destinationXlabel);
    		this.add(dx);
    		this.add(destinationYlabel);
    		this.add(dy);
    		
		    submitorderbutton = new JButton("Submit Order"); 
		    submitorderbutton.addActionListener(new MySubmitOrderListener());
            this.add(submitorderbutton);
       } 
	   public void UpdateOrderPanel(){
		   beginattack = false;
	   }
	   class MySubmitOrderListener implements ActionListener{
		   public void actionPerformed(ActionEvent a){
			 String selection = ordertypelist.getSelectedValue();
			 Territory source = theClient.GetMap().getTerritory((Integer.parseInt(sx.getText())), (Integer.parseInt(sy.getText())));
			 Territory destination = theClient.GetMap().getTerritory((Integer.parseInt(dx.getText())), (Integer.parseInt(dy.getText())));
			 int amount = Integer.parseInt(num.getText());
			 if (selection == "Move"){
			   Move newmove = new Move(theClient.GetPlayer(), source, destination, amount);	 
			   if (newmove.CheckOrder(theClient.GetMap()))
				 if (beginattack)
                   new MessageBox("You can't submit move order anymore!");
				 else {
					 theClient.addMove(newmove);
					 theClient.GetMap().SetupMap(newmove));
				 }
			 }
			 if (selection == "Attack"){
			   Attack newattack = new Attack(theClient.GetPlayer(), source, destination, amount);
			   if (newattack.CheckOrder(theClient.GetMap())){
			     theClient.addAttack(newattack);
			     beginattack = true;
			   }
			     
			 }	 
		   }
	   }
	    
   }
 
}
